//
//  View.cpp
//  C3W_Demo_By_Fan
//
//  Created by 范静涛 on 2024/7/22.
//

//------------------------------------------------------------------------------
//【文件名】View.cpp
//【功能模块和目的】界面类实现
//【开发者及日期】范静涛 2024/7/22
//【更改记录】2024/8/9 范静涛 同步更新了Controller成员标识符
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//各个成员函数流程和功能非常类似，仅前几个有函数体部分注释
//------------------------------------------------------------------------------

//自身类头文件
#include "View.hpp"
//std::iostream所属头文件
#include <iostream>
//std::string所属头文件
#include <string>
//std::shared_ptr所属头文件
#include <memory>
//控制器类所属头文件
#include "Controller.hpp"
using namespace std;

//简化类型名称长度，方便编码使用
using RES = Controller::RES;
using ModelInfo        = Controller::ModelInfo;
using PointInfo        = Controller::PointInfo;
using FaceInfo         = Controller::FaceInfo;
using LineInfo         = Controller::LineInfo;
using ModelInfoList    = Controller::ModelInfoList;
using FaceInfoList     = Controller::FaceInfoList;
using LineInfoList     = Controller::LineInfoList;
using PointInfoList    = Controller::PointInfoList;

//函数名：View
//功能：默认构造函数，调用显示主菜单
//入口参数：无
//出口参数：无
//返回值：无
View::View(){
    cout << MainMenu() << endl;
}
//------------------------------------------------------------------------------

//函数名：MainMenu
//功能：显示主菜单
//入口参数：无
//出口参数：无
//返回值：开发者信息字符串
string View::MainMenu() const{
    //获取控制器实例指针
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    //准备获取模型类比哦啊
    ModelInfoList InfoList;
    //用户所键入的选择
    string Selection;
    //非预期选择，循环显示菜单，要求用户再次键入选择
    while (Selection != "1" && Selection != "2" && Selection != "3"
           && Selection != "4" && Selection != "5" 
           && Selection != "6" && Selection != "7"){
        cout << "---C3W---" << endl;
        cout << "1. Models" << endl;
        cout << "2. Create" << endl;
        cout << "3. Import" << endl;
        cout << "4. Export" << endl;
        cout << "5. Select" << endl;
        cout << "6. Modify" << endl;
        cout << "7. Exit"   << endl << "(1/2/3/4/5/6/7):";
        
        //读取用户键入
        getline(cin, Selection);
        
        //根据选择触发下一级菜单显示
        if (Selection == "1") {
            cout << ListModelsMenu() << endl;
        }
        else if (Selection == "2") {
            cout << CreateModelMenu() << endl;
        }
        else if (Selection == "3") {
            cout << ImportModelMenu() << endl;
        }
        else if (Selection == "4") {
            cout << ExportModelMenu() << endl;
        }
        else if (Selection == "5") {
            cout << SelectModelMenu() << endl;
        }
        else if (Selection == "6") {
            cout << ModifyModelMenu() << endl;
        }
        else if (Selection == "7") {
            break;
        }
        //清除用户键入选择
        Selection.clear();
    }
    //返回开发者信息
    return "fanjingtao@tsinghua.edu.cn 2024.07.23";
}
//------------------------------------------------------------------------------

//函数名：ListModelsMenu
//功能：显示列出所有模型信息菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::ListModelsMenu() const{
    //获取控制器实例指针
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    //准备模型信息列表
    ModelInfoList InfoList;
    //用户键入选择
    string Selection;
    //非预期选择，循环显示菜单，要求用户再次键入选择
    while (Selection != "Y" && Selection != "y") {
        //获取模型信息
        Ctrller->ListModels(InfoList);
        //显示模型信息
        cout << endl << "---List All Models---" << endl;
        cout << InfoList.size() << " Model(s)" << endl;
        size_t i = 0;
        for (auto e : InfoList) {
            cout << "M[" << i 
                 << "]: FACE(" << e.FaceCount
                 << ") AREA(" << e.Area << ") LINE("
                 << e.LineCount << ") LEN(" << e.Length
                 << ") POINT(" << e.PointCount << ") VOL("
                 << e.Volumn << ")" << endl;
            i++;
        }
        //清空用户键入选择
        Selection.clear();
        //非预期选择，重新显示提示，要求输入输入
        while (Selection != "Y" && Selection != "N"
            && Selection != "y" && Selection != "n") {
            cout << endl << "Back to main menu? (Y/N):";
            //获取用户键入的选择
            getline(cin, Selection);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：SelectModelMenu
//功能：显示选择模型菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::SelectModelMenu() const{
    //获取控制器实例指针
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    //准备模型信息列表
    ModelInfoList InfoList;
    //用户键入选择
    string Selection;
    //非预期选择，循环显示菜单，要求用户再次键入选择
    while (Selection != "Y" && Selection != "y") {
        //调用控制器功能获取模型信息
        Ctrller->ListModels(InfoList);
        //显示模型信息
        cout << endl << "-Select Current Model-" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model is select as current" << endl;
        }
        else {
            cout << "M[" << Ctrller->CurrentModelIndex 
                 << "] is current" << endl;
        }
        if (InfoList.size() == 0) {
            cout << "No model can be select as current" << endl;
        }
        else{
            cout << "Model index(0~" << (InfoList.size() - 1) << "):";
            size_t Index;
            cin >> Index;
            cin.get();
            RES Res = Ctrller->SeleteCurrentModel(Index);
            if (Res != RES::OK) {
                cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
            }
        }
        Selection.clear();
        while (Selection != "Y" && Selection != "N" 
            && Selection != "y" && Selection != "n") {
            cout << endl << "Back to main menu? (Y/N):";
            getline(cin, Selection);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：CreateModelMenu
//功能：显示创建模型菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::CreateModelMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Selection;
    while (Selection != "Y" && Selection != "y") {
        cout << endl << "---Create Empty Model---" << endl;
        Ctrller->CreateAndSetToCurrent();
        cout << "1 empty model was created" << endl;
        cout << "M[" << Ctrller->CurrentModelIndex << "] is current" << endl;
        Selection.clear();
        while (Selection != "Y" && Selection != "N" 
            && Selection != "y" && Selection != "n") {
            cout << endl <<  "Back to main menu?" << endl 
            << "(Y/N? N for create another empty model):";
            getline(cin, Selection);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：ImportModelMenu
//功能：显示导入模型菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::ImportModelMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    ModelInfoList InfoList;
    string Selection;
    while (Selection != "Y" && Selection != "y") {
        Ctrller->ListModels(InfoList);
        cout << endl << "---Import Model From File---" << endl;
        if (InfoList.size() == 0) {
            cout 
            << "No model can be import from file, please create model first"
            << endl;
            return "";
        }
        cout << "File name:";
        string FileName;
        getline(cin, FileName);
        cout << "M[" << Ctrller->CurrentModelIndex << "] is current" << endl;
        cout << "Model index(0~" << (InfoList.size() - 1) << "):";
        size_t Index;
        cin >> Index;
        cin.get();
        RES Res = Ctrller->ImportModel(FileName, Index);
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        else {
            cout << "File: " << FileName 
                 << " has been imported to M[" << Index << "]" << endl;
        }
        Selection.clear();
        while (Selection != "Y" && Selection != "N" 
            && Selection != "y" && Selection != "n") {
            cout << endl <<  "Back to main menu?" << endl
                 << "(Y/N? N for import another file):";
            getline(cin, Selection);
        }
    }
    return "";
}

//函数名：ExportModelMenu
//功能：显示导出模型菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::ExportModelMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    ModelInfoList InfoList;
    string Selection;
    while (Selection != "Y" && Selection != "y") {
        Ctrller->ListModels(InfoList);
        cout << endl << "---Save Model To File---" << endl;
        if (InfoList.size() == 0) {
            cout 
            << "No model can be export to file, please create model first"
            << endl;
            return "";
        }
        cout << "File name:";
        string FileName;
        getline(cin, FileName);
        cout << "M[" << Ctrller->CurrentModelIndex << "] is current" << endl;
        cout << "Model index(0~" << (InfoList.size() - 1) << "):";
        size_t Index;
        cin >> Index;
        cin.get();
        RES Res = Ctrller->ExportModel(FileName, Index);
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        else {
            cout << "File: " << FileName 
                 << " has been exported from M[" << Index << "]" << endl;
        }
        Selection.clear();
        while (Selection != "Y" && Selection != "N" 
            && Selection != "y" && Selection != "n") {
            cout << endl <<  "Back to main menu?" << endl
                 << "(Y/N? N for export another file):";
            getline(cin, Selection);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：ModifyModelMenu
//功能：显示编辑模型菜单
//入口参数：无
//出口参数：无
//返回值：无
string View::ModifyModelMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "1" && Sel != "2" && Sel != "3"
           && Sel != "4" && Sel != "5" && Sel != "6" && Sel != "7" && Sel != "8"){
        cout << "---Modify Current Model---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout 
            << "No model has been selected as current,"
            << " please select model first" << endl;
            return "";
        }
        cout << "1. Model information" << endl;
        cout << "2. Append face" << endl;
        cout << "3. Remove face" << endl;
        cout << "4. Modify points in face" << endl;
        cout << "5. Append Line" << endl;
        cout << "6. Remove Line" << endl;
        cout << "7. Modify points in Line" << endl;
        cout << "8. Back to main menu" << endl << "(1/2/3/4/5/6/7/8):";
        
        getline(cin, Sel);
        
        if (Sel == "1") {
            cout << ListModelMenu() << endl;
        }
        else if (Sel == "2") {
            cout << AppendFaceMenu() << endl;
        }
        else if (Sel == "3") {
            cout << RemoveFaceMenu() << endl;
        }
        else if (Sel == "4") {
            cout << ModifyFacePointMenu() << endl;
        }
        else if (Sel == "5") {
            cout << AppendLineMenu() << endl;
        }
        else if (Sel == "6") {
            cout << RemoveLineMenu() << endl;
        }
        else if (Sel == "7") {
            cout << ModifyLinePointMenu() << endl;
        }
        else if (Sel == "8") {
            break;
        }
        Sel.clear();
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：ListModelMenu
//功能：显示列出模型信息菜单
//入口参数：无
//出口参数：无
//返回值：无
string View::ListModelMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---List All Faces & Lines---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
                 << " please select model first" << endl;
            return "";
        }
        ModelInfoList InfoList;
        Ctrller->ListModels(InfoList);
        cout << "Model[" << Ctrller->CurrentModelIndex 
             << "] is current model:" << endl;
        cout << "Name      : "
             << InfoList[Ctrller->CurrentModelIndex].Name << endl;
        cout << "Face count: "
             << InfoList[Ctrller->CurrentModelIndex].FaceCount << endl;
        cout << "Area      : "
             << InfoList[Ctrller->CurrentModelIndex].Area << endl;
        cout << "Line count: "
             << InfoList[Ctrller->CurrentModelIndex].LineCount << endl;
        cout << "Length    : "
             << InfoList[Ctrller->CurrentModelIndex].Length << endl;
        cout << "Volumn    : "
             << InfoList[Ctrller->CurrentModelIndex].Volumn << endl;
        FaceInfoList fInfoList;
        Ctrller->ListFacesInCurrentModel(fInfoList);
        size_t i = 0;
        for (auto e : fInfoList) {
            cout << "F[" << i << "](Area " << e.Area << ") : ";
            cout << "(" << e.PointsInfo[0].X << ", " 
                 << e.PointsInfo[0].Y << ", " <<e.PointsInfo[0].Z << ")-";
            cout << "(" << e.PointsInfo[1].X << ", "
                 << e.PointsInfo[1].Y << ", " <<e.PointsInfo[1].Z << ")-";
            cout << "(" << e.PointsInfo[2].X << ", "
                 << e.PointsInfo[2].Y << ", " <<e.PointsInfo[2].Z << ")"
                 << endl;
            i++;
        };
        LineInfoList lInfoList;
        Ctrller->ListLinesInCurrentModel(lInfoList);
        i = 0;
        for (auto e : lInfoList) {
            cout << "L[" << i << "](Length " << e.Length << ") : ";
            cout << "(" << e.PointsInfo[0].X << ", " 
                 << e.PointsInfo[0].Y << ", " <<e.PointsInfo[0].Z << ")-";
            cout << "(" << e.PointsInfo[1].X << ", "
                 << e.PointsInfo[1].Y << ", " <<e.PointsInfo[1].Z << ")"
                 << endl;
            i++;
        };

        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：AppendFaceMenu
//功能：显示添加面菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::AppendFaceMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---APPEND FACE---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
                 << " please select model first" << endl;
            return "";
        }
        double P0X;
        double P0Y;
        double P0Z;
        double P1X;
        double P1Y;
        double P1Z;
        double P2X;
        double P2Y;
        double P2Z;
        cout << "Point[0].X :";
        cin >> P0X;
        cout << "Point[0].Y :";
        cin >> P0Y;
        cout << "Point[0].Z :";
        cin >> P0Z;
        cout << "Point[1].X :";
        cin >> P1X;
        cout << "Point[1].Y :";
        cin >> P1Y;
        cout << "Point[1].Z :";
        cin >> P1Z;
        cout << "Point[2].X :";
        cin >> P2X;
        cout << "Point[2].Y :";
        cin >> P2Y;
        cout << "Point[2].Z :";
        cin >> P2Z;
        cin.get();
        RES Res = Ctrller->AppendFaceToCurrentModel(
            Face3D({P0X, P0Y, P0Z}, {P1X, P1Y, P1Z}, {P2X, P2Y, P2Z}));
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):" << endl 
                 << "(Y/N? N for append another face):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：AppendLineMenu
//功能：显示添加线菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::AppendLineMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---APPEND LINE---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
                 << " please select model first" << endl;
            return "";
        }
        double P0X;
        double P0Y;
        double P0Z;
        double P1X;
        double P1Y;
        double P1Z;
        cout << "Point[0].X :";
        cin >> P0X;
        cout << "Point[0].Y :";
        cin >> P0Y;
        cout << "Point[0].Z :";
        cin >> P0Z;
        cout << "Point[1].X :";
        cin >> P1X;
        cout << "Point[1].Y :";
        cin >> P1Y;
        cout << "Point[1].Z :";
        cin >> P1Z;
        cin.get();
        RES Res = Ctrller->AppendLineToCurrentModel(
            Line3D({P0X, P0Y, P0Z}, {P1X, P1Y, P1Z}));
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):" << endl 
                 << "(Y/N? N for append another line):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：RemoveFaceMenu
//功能：显示删除面菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::RemoveFaceMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---Remove Face---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
                 << " please select model first" << endl;
            return "";
        }
        size_t Index;
        FaceInfoList InfoList;
        Ctrller->ListFacesInCurrentModel(InfoList);
        if (InfoList.size() == 0) {
            cout << "No face in model" << endl;
            return "";
        }
        cout << "Face index(0~" << InfoList.size() - 1 << "):" << endl;
        cin >> Index;
        cin.get();
        RES Res = Ctrller->RemoveFaceFromCurrentModel(Index);
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):" << endl 
                 << "(Y/N? N for remove another face):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：RemoveLineMenu
//功能：显示删除线菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::RemoveLineMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---Remove Line---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
            << " please select model first" << endl;
            return "";
        }
        size_t Index;
        LineInfoList InfoList;
        Ctrller->ListLinesInCurrentModel(InfoList);
        if (InfoList.size() == 0) {
            cout << "No line in model" << endl;
            return "";
        }
        cout << "Line index(0~" << InfoList.size() - 1 << "):" << endl;
        cin >> Index;
        cin.get();
        RES Res = Ctrller->RemoveLineFromCurrentModel(Index);
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):" << endl
            << "(Y/N? N for remove another line):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：ModifyFacePointMenu
//功能：显示编辑面上点菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::ModifyFacePointMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---Modify Point In Face---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
                 << " please select model first" << endl;
            return "";
        }
        size_t Index;
        FaceInfoList InfoList;
        Ctrller->ListFacesInCurrentModel(InfoList);
        if (InfoList.size() == 0) {
            cout << "No face in model" << endl;
            return "";
        }
        cout << "Face index(0~" << InfoList.size() - 1 << "):";
        cin >> Index;
        cin.get();
        PointInfoList pInfoList;
        RES Res = Ctrller->ListPointsInFaceOfCurrentModel(Index, pInfoList);
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        else{
            cout << "Face[" << Index << "]:" << endl;
            cout << "Point[0]: (" << pInfoList[0].X << ", " 
                 << pInfoList[0].Y << ", " << pInfoList[0].Z << ")" << endl;
            cout << "Point[1]: (" << pInfoList[1].X << ", "
                 << pInfoList[1].Y << ", " << pInfoList[1].Z << ")" << endl;
            cout << "Point[2]: (" << pInfoList[2].X << ", "
                 << pInfoList[2].Y << ", " << pInfoList[2].Z << ")" << endl;
            size_t PointIndex;
            cout << "Point index(0~2):";
            cin >> PointIndex;
            double X;
            double Y;
            double Z;
            cout << "X:";
            cin >> X;
            cout << "Y:";
            cin >> Y;
            cout << "Z:";
            cin >> Z;
            cin.get();
            Res = Ctrller->ModifyPointInFaceOfCurrentModel
                (Index, PointIndex, {X, Y, Z});
            if (Res != RES::OK) {
                cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
            }
        }
        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):" << endl 
            << "(Y/N? N for modify another point in face):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------

//函数名：ModifyLinePointMenu
//功能：显示编辑线上点菜单
//入口参数：无
//出口参数：无
//返回值：空字符串
string View::ModifyLinePointMenu() const{
    shared_ptr<Controller> Ctrller = Controller::GetInstance();
    string Sel;
    while (Sel != "Y" && Sel != "y" ){
        cout << "---Modify Point In Line---" << endl;
        if (Ctrller->CurrentModelIndex == SIZE_T_MAX) {
            cout << "No model has been selected as current,"
                 << " please select model first" << endl;
            return "";
        }
        size_t Index;
        LineInfoList InfoList;
        Ctrller->ListLinesInCurrentModel(InfoList);
        if (InfoList.size() == 0) {
            cout << "No Line in model" << endl;
            return "";
        }
        cout << "Line index(0~" << InfoList.size() - 1 << "):";
        cin >> Index;
        cin.get();
        PointInfoList pInfoList;
        RES Res = Ctrller->ListPointsInLineOfCurrentModel(Index, pInfoList);
        if (Res != RES::OK) {
            cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
        }
        else{
            cout << "Line[" << Index << "]:" << endl;
            cout << "Point[0]: (" << pInfoList[0].X << ", " 
                 << pInfoList[0].Y << ", " << pInfoList[0].Z << ")" << endl;
            cout << "Point[1]: (" << pInfoList[1].X << ", "
                 << pInfoList[1].Y << ", " << pInfoList[1].Z << ")" << endl;
              size_t PointIndex;
            cout << "Point index(0~1):";
            cin >> PointIndex;
            double X;
            double Y;
            double Z;
            cout << "X:";
            cin >> X;
            cout << "Y:";
            cin >> Y;
            cout << "Z:";
            cin >> Z;
            cin.get();
            Res = Ctrller->ModifyPointInFaceOfCurrentModel
                (Index, PointIndex, {X, Y, Z});
            if (Res != RES::OK) {
                cout << Ctrller->RES_STR[static_cast<int>(Res)] << endl;
            }
        }
        Sel.clear();
        while (Sel != "Y" && Sel != "N" && Sel != "y" && Sel != "n") {
            cout << endl << "Back? (Y/N):" << endl 
                 << "(Y/N? N for modify another point in line):";
            getline(cin, Sel);
        }
    }
    return "";
}
//------------------------------------------------------------------------------
